import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx_controller_lifecycle/2%E3%80%81GetxController%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/life_cycle_controller1.dart';

import '../home_page.dart';
import 'life_cycle_controller2.dart';
import 'life_cycle_controller3.dart';
import 'life_cycle_controller4.dart';

/*
     GetX虽然各个功能均可单独引用使用，但是状态管理和路由是搭配的，如果没有使用 route_manager 组件，那么状态管理的生命周期就会失效。put的Controller在不使用的时候不会再被删除，而变成了应用状态常驻内存里。
     Get.put在Get路由环境以及原生路由环境下的区别
     在Getx路由环境，包括Get.to(()=>A())这种，controller和widget绑定，会随着页面一起创建和销毁，
     进页面：
     [GETX] Instance "CollectPageController" has been created
     [GETX] Instance "CollectPageController" has been initialized
     出页面：
     [GETX] "CollectPageController" onDelete() called
     [GETX] "CollectPageController" deleted from memory
     在非Getx路由环境（例如：Navigator.of(context).push(route)，调用Get.put的controller在退出页面的时候并不会自动从Get维护的内存中清除
*/

/// 1、调用完Get.put()且所在Widget加入Widget树后，才会调用onInit，onClose等生命周期函数
///   此案例中，在打印的信息中请观察
///   LifeCycleController2 一进入页面就会调用onInit方法
///   LifeCycleController1 会在加入加入到Widget树的时候调用onInit方法
///   LifeCycleController4则没有
///
/// 2、正常加入的Widget的GetxController的生命周期是和Get路由绑定在一起的，
///   这里说的生命周期是指controller实例是否在底层的Map中，和controller实例自身并无关
///   可以查看这篇文章：https://www.jianshu.com/p/a643a1f6074e
///   此案例中，观察LifeCycleController3，在进入页面的时候会调用onInit方法，在退出页面时会调用onClose
///
/// 3、Get底层维护了一个Map用来保存GetxController实例，Key是类名+tag
///   当controller所在的Widget加入Widget树后，会被put进Map，调用onInit
///   当controller所在的Widget退出路由后，会从Map删除，调用onClose
///   此案例中，观察LifeCycleController2和LifeCycleController4
///
/// 4、Get.put设定为全局变量时，只有在widget中被调用了，Get.put才是真正生效，否则Get.find会查找不到
///   此案例中，对比LifeCycleController2和LifeCycleController4
///   去除调‘注释111’后，则会报错，原因是Get.find<LifeCycleController4>找不到
///
/// 5、慎用Get.put()直接初始化全局变量，除非每次都调用Get.put不然很容易出问题
///   此案例中，第一次进入该页面是没问题的，但是如果退出当前页面再进入此页面时，就会因为
///   Get.find不到LifeCycleController2而报错

LifeCycleController1 controller1 = Get.put(LifeCycleController1());
LifeCycleController2 controller2 = Get.put(LifeCycleController2());
LifeCycleController4 controller4 = Get.put(LifeCycleController4());

class LifeCyclePage extends StatefulWidget {
  const LifeCyclePage({super.key});

  @override
  State<LifeCyclePage> createState() => _LifeCyclePageState();
}

class _LifeCyclePageState extends State<LifeCyclePage> {
  bool flag = false;
  final LifeCycleController3 controller3 = Get.put(LifeCycleController3());

  @override
  initState() {
    super.initState();

    //注释2
    Get.log("!!!!! controller2: $controller2");
    Future.delayed(const Duration(seconds: 3)).then((value) {
      setState(() {
        flag = true;
      });
    });
  }

  _addCount1() {
    controller1.counter += 1;
  }

  _addCount3() {
    controller3.counter += 1;
  }

  @override
  Widget build(BuildContext context) {
    Get.log("=== _LifeCyclePageState build");
    PageAction action = Get.arguments;
    return Scaffold(
        appBar: AppBar(
          title: Text(
            action.name,
            style: const TextStyle(
                fontSize: 14
            ),
          ),
        ),
        backgroundColor: Colors.white,
        body: SingleChildScrollView(
          child: Column(
            children: [
              const Padding(
                padding: EdgeInsets.all(15),
                child: Text(
                  """
1、调用完Get.put()且所在Widget加入Widget树后，才会调用onInit，onClose等生命周期函数

2、正常加入的Widget的GetxController的生命周期是和Get路由绑定在一起的，
   这里说的生命周期是指controller实例是否在底层的Map中，和controller实例自身并无关
   可以查看这篇文章：https://www.jianshu.com/p/a643a1f6074e

3、Get底层维护了一个Map用来保存GetxController实例，Key是类名+tag
   当controller所在的Widget加入Widget树后，会被put进Map，调用onInit
   当controller所在的Widget退出路由后，会从Map删除，调用onClose

4、Get.put设定为全局变量时，只有在widget中被调用了，Get.put才是真正失效，否则Get.find会查找不到

5、慎用Get.put()直接初始化全局变量，除非每次都调用Get.put不然很容易出问题
                  """,
                  maxLines: 100,
                  style: TextStyle(
                    fontSize: 15,
                  ),
                ),
              ),
              flag ? view1() : view2()
            ],
          ),
        )
    );
  }

  Widget view1() {
    // 注释3
    Widget widget2;
    Widget widget4 = const Text("");
    try {
      widget2 = GetBuilder<LifeCycleController2>(builder: (controller){
        return Text("count2:${controller.counter}");
      });
    }catch (e) {
      Get.log(">>> error:$e");
      widget2 = const Text("widget2 error");
    }
    // 注释111
    // try {
    //   widget4 = GetBuilder<LifeCycleController4>(builder: (controller){
    //     return Text("count4:${controller.counter}");
    //   });
    // }catch (e) {
    //   Get.log(">>> error:$e");
    //   widget4 = const Text("widget4 error");
    // }
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Obx(() => Text(
            "count1:${controller1.counter}"
        )),
        GetBuilder<LifeCycleController3>(
          builder: (controller) {
            return Text("count3:${controller.counter}");
          },
        ),
        const SizedBox(height: 15,),
        ElevatedButton(
            onPressed: _addCount1,
            child: const Text("count1 + 1")
        ),
        ElevatedButton(
            onPressed: _addCount3,
            child: const Text("count3 + 1")
        ),
        widget2,
        widget4,
      ],
    );
  }

  Widget view2() {
    return Container(
      height: 50,
      color: Colors.greenAccent,
    );
  }
}

